package com.yanqu.road.dao.impl.player;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserBlacklist;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ：zfr
 * @date ：2021/4/6 11:31
 */
public class CrossUserBlacklistDaoImpl extends TempDataObjectDao<UserBlacklist> {
    @Override
    protected boolean addData(UserBlacklist data) {
        PreparedStatement call = null;
        String sql = "INSERT INTO t_u_crossblacklist(userId,blacklistUserId,blacklistUserServerId,isDelete,userBaseInfo,type) " +
                "VALUES(?,?,?,?,?,?)";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareStatement(sql);
            int i = 1;
            call.setLong(i++, data.getUserId());
            call.setLong(i++, data.getBlacklistUserId());
            call.setLong(i++, data.getBlacklistUserServerId());
            call.setBoolean(i++, data.isDelete());
            if(data.getUserBaseInfo() == null){
                call.setString(i++, "{}");
            }else {
                call.setString(i++, JSON.toJSONString(data.getUserBaseInfo()));
            }
            call.setInt(i++, data.getType());
            return call.executeUpdate() > 0;
        } catch (Exception e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
        } finally {
            getDb().closeConnection(call, null);
        }
        return false;
    }

    @Override
    protected boolean updateData(UserBlacklist data) {
        PreparedStatement call = null;
        String sql = "UPDATE t_u_crossblacklist SET isDelete=?, userBaseInfo = ? WHERE userId=? and blacklistUserId=? and " +
                "blacklistUserServerId=? and type=?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareStatement(sql);
            int i = 1;
            call.setBoolean(i++, data.isDelete());
            if(data.getUserBaseInfo() == null){
                call.setString(i++, "{}");
            }else {
                call.setString(i++, JSON.toJSONString(data.getUserBaseInfo()));
            }
            call.setLong(i++, data.getUserId());
            call.setLong(i++, data.getBlacklistUserId());
            call.setLong(i++, data.getBlacklistUserServerId());
            call.setInt(i++, data.getType());
            return call.executeUpdate() > 0;
        } catch (Exception e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
        } finally {
            getDb().closeConnection(call, null);
        }
        return false;
    }

    @Override
    protected UserBlacklist parseData(ResultSet rs) throws SQLException {
        UserBlacklist data = new UserBlacklist();
        data.setUserId(rs.getLong("userId"));
        data.setBlacklistUserId(rs.getLong("blacklistUserId"));
        data.setBlacklistUserServerId(rs.getLong("blacklistUserServerId"));
        String baseUserInfoStr = rs.getString("userBaseInfo");
        if(baseUserInfoStr == null){
            baseUserInfoStr = "";
        }
        UserBaseInfo userBaseInfo = JSON.parseObject(baseUserInfoStr, new TypeReference<UserBaseInfo>() {});
        if(userBaseInfo != null) {
            data.setUserBaseInfo(userBaseInfo);
        }
        data.setDelete(rs.getBoolean("isDelete"));
        data.setType(rs.getInt("type"));
        return data;
    }

    public Map<Integer, Map<Long, Map<Long, UserBlacklist>>> getCrossUserBlacklistMap(long userId) {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Integer, Map<Long, Map<Long, UserBlacklist>>> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_u_crossblacklist where userId=?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setLong(1, userId);
            rs = call.executeQuery();
            while (rs.next()) {
                UserBlacklist data = parse(rs);
                if(!dataMap.containsKey(data.getType())){
                    dataMap.put(data.getType(), new ConcurrentHashMap<>());
                }
                Map<Long, Map<Long, UserBlacklist>> typeMap = dataMap.get(data.getType());
                if (!typeMap.containsKey(data.getBlacklistUserServerId())) {
                    typeMap.put(data.getBlacklistUserServerId(), new ConcurrentHashMap<>());
                }
                Map<Long, UserBlacklist> serverMap = typeMap.get(data.getBlacklistUserServerId());
                serverMap.put(data.getBlacklistUserId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    public Map<Long, Map<Integer, Map<Long, Map<Long, UserBlacklist>>>> getAllCrossUserBlacklistMap() {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Long, Map<Integer, Map<Long, Map<Long, UserBlacklist>>>> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_u_crossblacklist";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                UserBlacklist data = parse(rs);
                data.setUserBaseInfo(null);
                if(!dataMap.containsKey(data.getUserId())){
                    dataMap.put(data.getUserId(), new ConcurrentHashMap<>());
                }
                Map<Integer, Map<Long, Map<Long, UserBlacklist>>> userMap = dataMap.get(data.getUserId());
                if(!userMap.containsKey(data.getType())){
                    userMap.put(data.getType(), new ConcurrentHashMap<>());
                }
                Map<Long, Map<Long, UserBlacklist>> typeMap = userMap.get(data.getType());
                if (!typeMap.containsKey(data.getBlacklistUserServerId())) {
                    typeMap.put(data.getBlacklistUserServerId(), new ConcurrentHashMap<>());
                }
                Map<Long, UserBlacklist> serverMap = typeMap.get(data.getBlacklistUserServerId());
                serverMap.put(data.getBlacklistUserId(), data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }
}
